from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://tuple:123456@192.168.1.116:3306/test_sa?charset=utf8')
# 我们不能直接把Python原生的类，变成表
# 需要从sa里面获得一个基类
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()  # 用来继承的基类


from sqlalchemy import Column, Integer, String  # String对应的是varchar
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship  # 关系


# 用户表
class User(Base): # 自己的类，必须要继承自Base
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(20))

    seller = relationship('Seller', uselist=False, back_populates='user') # back_populates要填对面的关系
    # 在一对一的时候，被关联的这一头需要使用uselist=False

from sqlalchemy import Table  # 中间表不使用class，而使用Table
seller_tags = Table('seller_tags', Base.metadata,
    Column('seller_id', Integer, ForeignKey('sellers.id'), primary_key=True),
    Column('tag_id', Integer, ForeignKey('tags.id'), primary_key=True),
)


class Seller(Base):
    __tablename__ = 'sellers'

    id = Column(Integer, primary_key=True)
    
    user_id = Column(Integer, ForeignKey('users.id'), unique=True)
    user = relationship('User', back_populates='seller')
    houses = relationship('House', back_populates='seller')

    tags = relationship('Tag', secondary=seller_tags, back_populates='sellers')


class Tag(Base):
    __tablename__ = 'tags'

    id = Column(Integer, primary_key=True)
    name = Column(String(20))
    sellers = relationship('Seller', secondary=seller_tags, back_populates='tags')


class House(Base):
    __tablename__ = 'houses'

    id = Column(Integer, primary_key=True)
    summary = Column(String(100))

    seller_id = Column(Integer, ForeignKey('sellers.id'))

    seller = relationship('Seller', back_populates='houses')


# Base包含了所有孩子的细节
Base.metadata.create_all(engine)


from sqlalchemy.orm import sessionmaker
session = sessionmaker(bind=engine)()
# user1 = User(name='Tuple')
# session.add(user1)
# session.commit()

# for i in range(10):
#     session.add(User(name='Tuple'+str(i)))
# session.commit()

# for i in session.query(User):
#     if i.name == 'Tuple':
#         session.delete(i)
# session.commit()

# for i in session.query(User):
#     if i.id > 7:
#         i.name = i.name.replace('Tuple', 'Taka')
# session.commit()

# for i in session.query(Seller):
#     print(i.houses)


# 如果发现这个表已经存在了，那么不会再重建一次。
# 如果你这个表存在了，但是和类设计的不一样，也不会重新覆盖
# 1. 做开发的，没权利接触到真的数据
# 2. 其次，sqlalchemy其实可以有办法修改，而不删除，但是，需要使用到别的插件

# import *
# 你会把所有的变量全部导入，假如你自己写了包，里面有个函数叫open，open就把我们open内置函数覆盖掉了

# 为什么一对多不要uselist(use 使用， list列表)
# 卖家和房子，一个卖家要对应多个房子
# uselist= True 默认不用写

# 可不可以，先用SQL把数据库建好，然后再直接写类来使用：可以！但是，类必须和表对应。

# 用ORM原因是什么？
# 我需要在Python层面表达出数据库（是不是应该表达对？）
# 我们不像写SQL，我们不像处理太多 不同数据库之间的差别， 所以，我们把所有的东西，都用Python来写

# ORM查询效率比SQL高吗？
# 不可能，因为ORM是帮你把Python代码转换成SQL代码
# 

